package org.rednebula.framework.core;

import java.io.Serializable;

import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.IdentityService;
import org.jbpm.api.ManagementService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskService;
import org.rednebula.framework.core.context.FlowContext;
import org.rednebula.framework.core.context.InternalServletContext;
import org.rednebula.framework.core.context.RequestContext;
import org.rednebula.framework.core.context.SessionContext;
import org.rednebula.framework.core.context.SpringContext;
import org.rednebula.framework.core.context.ValueStackContext;
import org.rednebula.framework.core.log.Log;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;


public class ProcedureEngine extends BasicContext implements IProcedureEngine,
		Serializable, IEnvironmentFactory, DisposableBean {

	/**
	 * 
	 */

	protected static Log logger = Log.getLog(ProcedureEngine.class);

	IConfiguration configuration;

	SessionContext sessionContext = new SessionContext();

	RequestContext requestContext = new RequestContext();

	InternalServletContext servletContext = new InternalServletContext();

	ValueStackContext valueStackContext = new ValueStackContext();

	@Autowired
	ProcessEngine processEngine;

	public ProcedureEngine() {
		super();
		this.setName(PROCEDUREENGINE);
	}

	public RequestContext getRequestContext() {
		return requestContext;
	}

	public InternalServletContext getServletContext() {
		return servletContext;
	}

	public void setServletContext(InternalServletContext servletContext) {
		this.servletContext = servletContext;
	}

	public void setRequestContext(RequestContext requestContext) {
		this.requestContext = requestContext;
	}

	public ValueStackContext getValueStackContext() {
		return valueStackContext;
	}

	public void setValueStackContext(ValueStackContext valueStackContext) {
		this.valueStackContext = valueStackContext;
	}

	public void setSessionContext(SessionContext sessionContext) {
		this.sessionContext = sessionContext;
	}

	public SessionContext getSessionContext() {
		return sessionContext;
	}

	public IConfiguration getConfiguration() {
		return configuration;
	}

	public void setConfiguration(IConfiguration configuration) {
		this.configuration = configuration;
	}

	public <T> T get(String key) {
		return (T) getEnvironment().lookup(key);
	}

	public <T> T get(Class<T> type) {
		return (T) getEnvironment().lookup(type.getName());
	}

	public String getName() {
		return this.name;
	}

	public boolean has(String name) {
		return false;
	}

	public ProcessEngine getProcessEngine() {
		return processEngine;
	}

	public void setProcessEngine(ProcessEngine processEngine) {
		this.processEngine = processEngine;
	}

	public AbstractEnvironmentImpl getEnvironment() {
		AbstractEnvironmentImpl envi = AbstractEnvironmentImpl.getCurrent();
		try {
			if ( envi== null) {
				envi = (AbstractEnvironmentImpl) this.getConfiguration()
						.getEnvironmentImpl();
				AbstractEnvironmentImpl.setEnvironment(envi);
	
				
				envi.setContext(this.getValueStackContext());
				envi.setEngine(this);
				envi.setContext(this.getServletContext());
				envi.setContext(this.getSessionContext());
				envi.setContext(this.getRequestContext());

			}
			
		} catch (Exception g) {

		}
		return envi;
	}

	public void close() {
		if (processEngine != null) {
			processEngine.close();
			processEngine = null;
		}
	}

	public RepositoryService getRepositoryService(){
		return this.getProcessEngine().getRepositoryService();
	}
	
	public HistoryService getHistoryService(){
		return this.getProcessEngine().getHistoryService();
	}
	
	public IdentityService getIdentityService(){
		return getProcessEngine().getIdentityService();
	}
	
	public ManagementService getManagementService(){
		return getProcessEngine().getManagementService();
	}
	
	public TaskService getTaskService(){
		return this.getProcessEngine().getTaskService();
	}
	
	public ExecutionService getExecutionService(){
		return this.getProcessEngine().getExecutionService();
	}
	public void destroy() throws Exception {
		close();
		
	}
}
